﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;

namespace Indigo.Quibbler.Common
{
    [TemplatePart(Name = "template_btnMinimize", Type = typeof(ImageButton))]
    [TemplatePart(Name = "template_btnMaximize", Type = typeof(ImageButton))]
    [TemplatePart(Name = "template_btnClose", Type = typeof(ImageButton))]
    [TemplatePart(Name = "template_titleBar", Type = typeof(FrameworkElement))]
    [TemplatePart(Name = "template_windowResizer", Type = typeof(ResizeGrip))]
    [TemplatePart(Name = "template_windowBackground", Type = typeof(Border))]
    public class QuibblerWindow : Window
    {
        #region Constants
        private const string IMAGE_MAXIMIZE = "pack://application:,,/Quibbler - Universal News Reader;component/Images/WindowCascade.png";
        private const string IMAGE_MAXIMIZE_HOVER = "pack://application:,,/Quibbler - Universal News Reader;component/Images/WindowCascade.png";
        private const string IMAGE_MAXIMIZE_PRESSED = "pack://application:,,/Quibbler - Universal News Reader;component/Images/WindowCascade.png";
        private const string IMAGE_RESTORE = "pack://application:,,/Quibbler - Universal News Reader;component/Images/WindowCascade.png";
        private const string IMAGE_RESTORE_HOVER = "pack://application:,,/Quibbler - Universal News Reader;component/Images/WindowCascade.png";
        private const string IMAGE_RESTORE_PRESSED = "pack://application:,,/Quibbler - Universal News Reader;component/Images/WindowCascade.png";
        #endregion

        #region Child Controls
        ImageButton _btnMinimize = null;
        ImageButton _btnMaximize = null;
        ImageButton _btnClose = null;
        FrameworkElement _titleBar = null;
        ResizeGrip _windowResizer = null;
        Border _windowBackground = null;
        #endregion

        #region Private Objects
        private Point _startPoint;
        private Size _originalSize;
        #endregion

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _RegisterChildControls();
            _OnWindowStateChanged(this.WindowState);

            this.Loaded += new RoutedEventHandler(QuibblerWindow_Loaded);
            this.StateChanged += new EventHandler(QuibblerWindow_StateChanged);
        }

        void QuibblerWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _OnWindowStateChanged(this.WindowState);
        }

        void QuibblerWindow_StateChanged(object sender, EventArgs e)
        {
            _OnWindowStateChanged(this.WindowState);
        }

        #region Event Handlers
        private void _btnMinimize_Click(object sender, EventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        void _btnMaximize_Click(object sender, EventArgs e)
        {
            WindowState newState =  (WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
            _OnWindowStateChanged(newState);
            WindowState = newState;
        }

        private void _btnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        void _titleBar_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Debug.WriteLine("Click count: " + e.ClickCount);
            if (e.ClickCount >= 2)
                WindowState = (WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
            else
                DragMove();
        }

        #endregion

        #region Private Methods
        private void _RegisterChildControls()
        {
            try
            {
                _btnMinimize = _GetChildControl<ImageButton>("template_btnMinimize");
                if (_btnMinimize != null) _btnMinimize.Click += new EventHandler(_btnMinimize_Click);
            }
            catch { }

            try
            {
                _btnMaximize = _GetChildControl<ImageButton>("template_btnMaximize");
                if (_btnMaximize != null) _btnMaximize.Click += new EventHandler(_btnMaximize_Click);
            }
            catch { }

            try
            {
                _btnClose = _GetChildControl<ImageButton>("template_btnClose");
                if (_btnClose != null) _btnClose.Click += new EventHandler(_btnClose_Click);
            }
            catch { }

            try
            {
                _titleBar = _GetChildControl<FrameworkElement>("template_titleBar");
                if (_titleBar != null) _titleBar.MouseLeftButtonDown += new MouseButtonEventHandler(_titleBar_MouseLeftButtonDown);
            }
            catch { }

            try
            {
                _windowResizer = _GetChildControl<ResizeGrip>("template_windowResizer");
                _windowResizer.MouseLeftButtonDown += new MouseButtonEventHandler(_windowResizer_MouseLeftButtonDown);
                _windowResizer.MouseMove += new MouseEventHandler(_windowResizer_MouseMove);
                _windowResizer.MouseLeftButtonUp += new MouseButtonEventHandler(_windowResizer_MouseLeftButtonUp);
            }
            catch { }

            try { _windowBackground = _GetChildControl<Border>("template_windowBackground"); }
            catch { }
        }

        void _windowResizer_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (_windowResizer != null && _windowResizer.IsMouseCaptured)
                _windowResizer.ReleaseMouseCapture();
        }

        void _windowResizer_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton != MouseButtonState.Pressed || _windowResizer == null) return;

            Point currentPoint = e.GetPosition(null);
            Debug.WriteLine("Resize Drag: " + currentPoint);
            this.Width = _originalSize.Width + (currentPoint.X - _startPoint.X);
            this.Height = _originalSize.Height + (currentPoint.Y - _startPoint.Y);
        }

        void _windowResizer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (_windowResizer != null)
            {
                Debug.WriteLine("Resize Start: " + _startPoint);
                _originalSize = new Size(this.ActualWidth, this.ActualHeight);
                _startPoint = e.GetPosition(null);
                _windowResizer.CaptureMouse();
            }
        }

        private void _OnWindowStateChanged(WindowState windowState)
        {
            if (_btnMaximize != null)
            {
                _btnMaximize.ImageSource = (windowState == WindowState.Normal) ? IMAGE_MAXIMIZE : IMAGE_RESTORE;
                _btnMaximize.HoverImageSource = (windowState == WindowState.Normal) ? IMAGE_MAXIMIZE_HOVER : IMAGE_RESTORE_HOVER;
            }

            if (_windowResizer != null)
                _windowResizer.Visibility = (windowState == WindowState.Maximized) ? Visibility.Collapsed : Visibility.Visible;

            // WORKAROUND: For same resolution, in Windows XP and Windows 7, maximized window has different sizes.
            //if (_windowBackground != null)
            //    _windowBackground.Background = (windowState == WindowState.Maximized) ? new SolidColorBrush(Colors.Black) : null;
        }
        #endregion

        #region Helper Methods
        private T _GetChildControl<T>(string ctrlName) where T : DependencyObject
        {
            T ctrl = GetTemplateChild(ctrlName) as T;
            return ctrl;
        }

        private BitmapImage _GetImage(string appRelativeUrl)
        {
            Uri imageUri = new Uri(appRelativeUrl, UriKind.Relative);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            image.UriSource = imageUri;
            image.EndInit();
            return image;
        }
        #endregion
    }
}
